import datetime
import hashlib
import logging
import os
import random
import uuid
from collections import Counter
from datetime import datetime

import jieba
import pandas as pd
import pytz
import requests
from django.core.files.storage import FileSystemStorage
from rest_framework import status
from rest_framework.views import APIView
from tqdm import tqdm

from Util.BaseResponse import BaseResponse
from WeiChat import settings
from app.Type import types
from app.views import contact, self_message, other_message, config
from tools import EMOJIS


def download_emoji(url):
    response = requests.get(url, headers={
        'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                      "Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"})
    # 获取文件类型
    file_extension = ".jpg"
    # 计算文件内容的哈希值
    content_hash = hashlib.sha256(response.content).hexdigest()

    # 检查是否已经存在相同内容的文件
    for filename in os.listdir(settings.STATIC_ROOT):
        file_path = os.path.join(settings.STATIC_ROOT, filename)
        if os.path.isfile(file_path):
            with open(file_path, "rb") as file:
                # 计算文件内容的哈希值
                existing_content_hash = hashlib.sha256(file.read()).hexdigest()
                # 如果存在相同内容的文件，则返回旧文件名
                if content_hash == existing_content_hash:
                    return filename

    # 生成新文件名
    new_filename = str(uuid.uuid4()) + file_extension

    # 保存图片文件
    fs = FileSystemStorage(location=settings.STATIC_URL)
    with fs.open(new_filename, 'wb') as destination:
        destination.write(response.content)

    # 返回新文件名
    return new_filename


def get_world_cloud(merged_data):
    jieba.setLogLevel(logging.INFO)
    STOPWORDS = open("data/stopwords.txt", "r", encoding="utf-8").read().split("\n")
    STOPWORDS = set(STOPWORDS + ["\r\n"])
    all_words = []
    for i, row in tqdm(merged_data.iterrows(), total=len(merged_data)):
        row_content = row["StrContent"]
        for emoji in EMOJIS:
            row_content = row_content.replace(emoji, " ")
        words = jieba.lcut(row_content)
        for word in words:
            if len(word) > 1 and word not in STOPWORDS:
                all_words.append(word)
    cnt = sorted(Counter(all_words).items(), key=lambda x: x[1], reverse=True)
    # text = " ".join(all_words)
    # wc = WordCloud(font_path="data/simhei.ttf", background_color="white", max_words=2000,
    #                stopwords=STOPWORDS, max_font_size=200, min_font_size=6,
    #                width=1080, height=720, random_state=42,
    #                repeat=False, collocations=False, )
    # wc.generate(text)
    # plt.figure(figsize=(12, 12))
    # plt.imshow(wc, interpolation="bilinear")
    # plt.axis("off")
    # plt.savefig("wordcloud.png")
    #
    # if os.path.exists("static/wordcloud.png"):
    #     # 如果文件存在，删除文件
    #     os.remove("static/wordcloud.png")
    # os.rename("wordcloud.png", "static/wordcloud.png")

    datas = []
    for i in range(len(cnt)):
        data = {
            "name": cnt[i][0],
            "value": cnt[i][1]
        }
        datas.append(data)

    return datas


class WordAPIView(APIView):
    before_time = '2023-01-01'
    end_time = '2024-01-01'

    def get(self, request):
        contact_name = request.query_params.get('name')
        if contact_name is None:
            contact_name = "yyyy"

        print(contact_name)
        self_other_message = self_message[self_message['NickName'] == contact_name]
        other_self_message = other_message[other_message['NickName'] == contact_name]

        # 将字符串日期转换为 datetime 对象
        before_datetime = datetime.strptime(self.before_time, '%Y-%m-%d')
        end_datetime = datetime.strptime(self.end_time, '%Y-%m-%d')
        before_timestamp = int(before_datetime.timestamp())
        end_timestamp = int(end_datetime.timestamp())

        self_other_message_filtered = self_other_message[
            (self_other_message['CreateTime'] >= before_timestamp) &
            (self_other_message['CreateTime'] <= end_timestamp)
            ]

        other_self_message_filtered = other_self_message[
            (other_self_message['CreateTime'] >= before_timestamp) &
            (other_self_message['CreateTime'] <= end_timestamp)
            ]

        merged_data = pd.concat([self_other_message_filtered, other_self_message_filtered])
        filtered_data = merged_data[merged_data['Type'] == types["文本"]]

        data = {
            "wordcloud": get_world_cloud(filtered_data),
        }

        return BaseResponse(data=data, status=status.HTTP_200_OK).success()


class Annual(APIView):
    before_time = '2023-01-01'
    end_time = '2024-01-01'

    def get(self, request, format=None):
        contact_name = request.query_params.get('name')
        if contact_name is None:
            contact_name = "yyyy"

        contact_info = contact[contact['NickName'] == contact_name].iloc[0]
        self_other_message = self_message[self_message['NickName'] == contact_name]
        other_self_message = other_message[other_message['NickName'] == contact_name]

        # 找到两张表最找的记录取min
        earliest_self_message = self_other_message.sort_values(by="CreateTime").head(1)
        earliest_other_message = other_self_message.sort_values(by="CreateTime").head(1)
        first_day = None
        try:
            first_day = min(int(earliest_self_message['CreateTime'].iloc[0]),
                            int(earliest_other_message['CreateTime'].iloc[0]))
        except:
            if len(earliest_self_message):
                first_day = int(earliest_self_message['CreateTime'].iloc[0])
            if len(earliest_other_message):
                first_day = int(earliest_other_message['CreateTime'].iloc[0])

        utc_datetime = datetime.utcfromtimestamp(first_day)
        local_timezone = pytz.timezone('Asia/Shanghai')
        local_datetime = utc_datetime.astimezone(local_timezone)
        current_time = datetime.now(local_timezone)
        time_difference = current_time - local_datetime
        seconds_difference = time_difference.total_seconds()
        formatted_date = local_datetime.strftime('%Y 年 %m 月 %d 日')

        # 将字符串日期转换为 datetime 对象
        before_datetime = datetime.strptime(self.before_time, '%Y-%m-%d')
        end_datetime = datetime.strptime(self.end_time, '%Y-%m-%d')
        before_timestamp = int(before_datetime.timestamp())
        end_timestamp = int(end_datetime.timestamp())

        self_other_message_filtered = self_other_message[
            (self_other_message['CreateTime'] >= before_timestamp) &
            (self_other_message['CreateTime'] <= end_timestamp)
            ]

        other_self_message_filtered = other_self_message[
            (other_self_message['CreateTime'] >= before_timestamp) &
            (other_self_message['CreateTime'] <= end_timestamp)
            ]

        merged_data = pd.concat([self_other_message_filtered, other_self_message_filtered])
        filtered_data = merged_data[merged_data['Type'] == types["文本"]]

        # 计算满足条件的记录中 StrContent 字段的总字数
        total_chars = filtered_data['StrContent'].str.len().sum()

        # 计算每个月的聊天数量
        merged_data['CreateTime'] = pd.to_datetime(merged_data['CreateTime'], unit='s')
        monthly_chat_counts = merged_data.groupby(merged_data['CreateTime'].dt.to_period('M')).size()
        max_chat_month = monthly_chat_counts.idxmax()
        max_chat_count = monthly_chat_counts[max_chat_month]
        min_chat_month = monthly_chat_counts.idxmin()
        min_chat_count = monthly_chat_counts[min_chat_month]
        chinese_month_dict = {
            1: '一月', 2: '二月', 3: '三月', 4: '四月', 5: '五月', 6: '六月',
            7: '七月', 8: '八月', 9: '九月', 10: '十月', 11: '十一月', 12: '十二月'
        }
        max_chat_month_chinese = chinese_month_dict[max_chat_month.month]
        min_chat_month_chinese = chinese_month_dict[min_chat_month.month]
        message_dates = merged_data['CreateTime'].dt.date.unique()

        # 计算消息记录的天数
        days_with_messages = len(message_dates)

        emoji_messages = merged_data[merged_data['Type'] == types["表情包"]]

        emoji_counts = emoji_messages['StrContent'].value_counts()

        # 找到发送次数最多的表情包
        top_emoji = emoji_counts.head(min(5, len(emoji_counts)))

        import xml.etree.ElementTree as ET

        rank = 1
        emoji_top_five = []

        for emoji, count in top_emoji.items():
            item = {}

            xml_string = str(emoji)
            root = ET.fromstring(xml_string)
            # 提取表情包原图 URL
            emoji_url = root.find('emoji').attrib['cdnurl']
            item["rank"] = rank
            item["emoji_url"] = emoji_url
            item["emoji_num"] = count
            emoji_top_five.append(item)
            rank += 1

        max_emoji_num = emoji_top_five[0]['emoji_num']
        emoji_url = emoji_top_five[0]['emoji_url']

        text_message = merged_data[merged_data['Type'] == types["文本"]]
        text_counts = text_message['StrContent'].value_counts()

        text_top = text_counts.head(min(5 , len(text_counts)))

        rank = 1
        text_top_five = []
        for text, count in text_top.items():
            item = {"rank": rank, "text": text, "count": count}
            text_top_five.append(item)
            rank += 1

        data = {
            "my_avatar": config.my_avatar_url,
            "his_avatar": contact_info["smallHeadImgUrl"],
            "his_big_avatar": contact_info["bigHeadImgUrl"],
            "my_nick_name": config.my_wechat_name,
            "his_nick_name": contact_info["NickName"],
            "first_chat_date": formatted_date,
            "duration": seconds_difference * 1000,
            "total_msg_num": len(other_self_message) + len(self_other_message),
            "total_num": total_chars,

            "max_month": max_chat_month_chinese,
            "max_month_num": max_chat_count,
            "min_month": min_chat_month_chinese,
            "min_month_num": min_chat_count,

            "year": before_datetime.year,
            "chat_days": days_with_messages,

            "emoji_total_num": len(emoji_messages),
            "emoji_url": emoji_url,
            "emoji_num": max_emoji_num,
            "emoji_top_five": emoji_top_five,

            "keyword": text_top_five[0]["text"],
            "keyword_max_num": text_top_five[0]["count"],
            "keyword_top_five": text_top_five,

            "score": random.randint(75, 90),
        }

        return BaseResponse(data=data, status=status.HTTP_200_OK).success()
